package cn.ilikes.tools.nosql.jpa.clients;

import org.slf4j.Logger;

import cn.ilikes.tools.logs.Loggerfactory;
import cn.ilikes.tools.nosql.jpa.JPASQLPersistenUnitEnv;
import cn.ilikes.tools.nosql.jpa.SysConfigs;
import cn.ilikes.tools.nosql.jpa.clients.handers.AbDataHander;
import cn.ilikes.tools.nosql.jpa.clients.handers.DefultDataHanderFactory;
import cn.ilikes.tools.nosql.jpa.clients.handers.IDataHanderFactory;
import cn.ilikes.tools.nosql.jpa.clients.handers.JPASQLDataHnaderException;
import cn.ilikes.tools.nosql.jpa.clients.indexs.ABClientIndex;
import cn.ilikes.tools.nosql.jpa.clients.indexs.ClientIndexingException;
import cn.ilikes.tools.nosql.jpa.clients.indexs.DefultClientIndexerFactory;
import cn.ilikes.tools.nosql.jpa.clients.indexs.IClientIndexerFactory;
import cn.ilikes.tools.nosql.jpa.clients.schemas.DefultSchemaManagerFactory;
import cn.ilikes.tools.nosql.jpa.clients.schemas.ISchemaManager;
import cn.ilikes.tools.nosql.jpa.clients.schemas.ISchemaManagerFactory;

public class DefultClientFactory extends ClientFactoryImple implements ClientFactory {

	private Logger logger = Loggerfactory.instance(DefultClientFactory.class);

	private IDataHanderFactory dataHanderFactory;

	private IClientIndexerFactory clientIndexerFactory;

	public DefultClientFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		super(persistenUnitEnv);

	}

	private void setClientIndexerFactory(IClientIndexerFactory clientIndexerFactory) {
		this.clientIndexerFactory = clientIndexerFactory;
	}

	@Override
	public void init() {
		Loggerfactory.info(logger, "Start init " + getPersistenUnitEnv().getPersistenUnitName() + " 's  Client  Factory ");
		JPASQLPersistenUnitEnv persistenUnitEnv = getPersistenUnitEnv();
		initSchemas(persistenUnitEnv);
		initDataHanderFactory(persistenUnitEnv);
		initClientIndexerFactory(persistenUnitEnv);

	}

	private void initSchemas(JPASQLPersistenUnitEnv persistenUnitEnv) {
		String ddl_Auto = persistenUnitEnv.getPersistenceUnitMetadata().getProperties().getProperty(SysConfigs.jpa_ddl_auto);
		if (ddl_Auto == null || ddl_Auto.equals(ISchemaManager.ExecType.no.toString()))
			return;
		ISchemaManagerFactory schemaManagerFactory = new DefultSchemaManagerFactory(persistenUnitEnv);
		schemaManagerFactory.createSchema();
	}

	private void initDataHanderFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		Loggerfactory.info(logger, "Start  Create " + persistenUnitEnv.getPersistenUnitName() + " Defult  Data Hander Factory  ! ");
		IDataHanderFactory dataHanderFactory = new DefultDataHanderFactory(getPersistenUnitEnv());
		dataHanderFactory.init();
		dataHanderFactory.open();
		setDataHanderFactory(dataHanderFactory);
	}

	private void initClientIndexerFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		Loggerfactory.info(logger, "Start  Create " + persistenUnitEnv.getPersistenUnitName() + " Defult  Client Indexer Factory  ! ");
		IClientIndexerFactory clientIndexerFactory = new DefultClientIndexerFactory(persistenUnitEnv);
		clientIndexerFactory.init();
		clientIndexerFactory.open();
		setClientIndexerFactory(clientIndexerFactory);
	}

	@Override
	public void close() {
		dataHanderFactory.close();
		clientIndexerFactory.close();
	}

	@Override
	public AbClient createClient() throws JPASQLClientsException {
		try {
			AbDataHander dataHander = dataHanderFactory.createAbDataHander();
			ABClientIndex clientIndex = clientIndexerFactory.createClientIndex();
			JPASQLPersistenUnitEnv persistenUnitEnv = getPersistenUnitEnv();
			AbClient client = new HbaseClient(dataHander, clientIndex, persistenUnitEnv);
			return client;
		} catch (JPASQLDataHnaderException e) {
			Loggerfactory.error(logger, e.getMessage());
			throw new JPASQLClientsException(e);
		} catch (ClientIndexingException e) {
			Loggerfactory.error(logger, e.getMessage());
			throw new JPASQLClientsException(e);
		}
	}

	@Override
	public boolean isOpen() {
		return (dataHanderFactory.isOpen() && clientIndexerFactory.isOpen());
	}

	@Override
	public void open() {
		dataHanderFactory.open();
		clientIndexerFactory.open();

	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	private void setDataHanderFactory(IDataHanderFactory dataHanderFactory) {
		this.dataHanderFactory = dataHanderFactory;
	}

}
